package me.sdevil507.mobile.wxApplet.service.impl;

import com.querydsl.jpa.impl.JPAQueryFactory;
import me.sdevil507.biz.fruit.repository.FruitAuthorRepository;
import me.sdevil507.biz.fruit.repository.FruitOrgRelRepository;
import me.sdevil507.mobile.wxApplet.dto.BwechatUserDTO;
import me.sdevil507.mobile.wxApplet.entity.BwechatUserPO;
import me.sdevil507.mobile.wxApplet.model.WxBO;
import me.sdevil507.mobile.wxApplet.repository.BwechatUserRepository;
import me.sdevil507.mobile.wxApplet.service.WxCheckUserService;
import me.sdevil507.mobile.wxApplet.service.WxWebService;
import me.sdevil507.org.po.*;
import me.sdevil507.org.repository.*;
import me.sdevil507.org.service.OrgDeptService;
import me.sdevil507.org.service.OrgInviteService;
import me.sdevil507.org.service.OrgUserService;
import me.sdevil507.supports.result.ApiResultDTO;
import me.sdevil507.supports.result.ApiResultGenerator;
import me.sdevil507.supports.util.JwtUtil;
import me.sdevil507.supports.util.RegularExpressionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class WxWebServiceImpl implements WxWebService {

    @Autowired
    OrgDeptService orgDeptService;
    @Autowired
    BwechatUserRepository bwechatUserRepository;
    @Autowired
    private TempExpertRepository tempExpertRepository;
    @Autowired
    private OrgRepository orgRepository;
    @Autowired
    private OrgUserRepository orgUserRepository;
    @Autowired
    private OrgUserRelRepository orgUserRelRepository;
    @Autowired
    private OrgExpertInfoRepository orgExpertInfoRepository;
    @Autowired
    private FruitAuthorRepository fruitAuthorRepository;
    @Autowired
    private FruitOrgRelRepository fruitOrgRelRepository;
    @Autowired
    private WxCheckUserService wxCheckUserService;
    @Autowired
    private OrgInviteService orgInviteService;
    @Autowired
    OrgUserService usersService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Override
    public ApiResultDTO loginAndGetInfo(String mobile, WxBO wxBO) {
        ApiResultDTO apiResultDTO;

        BwechatUserDTO info = new BwechatUserDTO();
        info.setPhone(mobile);
        try {
            //用户登录： 用手机号找到user
            OrgUserPo users = usersService.readOneByPhoneNumber(mobile);
            if(users != null){
                info.setRealName(users.getRealName());
                //返回全职单位机构
                List<OrgUserRelPo> orgUserRels = users.getOrgUserRel().stream().filter(OrgUserRelPo::isExpert).collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(orgUserRels)){
                    info.setOrgName(orgUserRels.get(0).getOrg().getTitle());
                    info.setUserRole("1");
                }
            }else{
                //临时专家或者无此专家
                info.setUserRole("2");
            }
        }catch (Exception e){
            e.printStackTrace();
            apiResultDTO = ApiResultGenerator.create("-1", "当前手机号存在多个用户记录，请联系管理员修改！!");
            return apiResultDTO;
        }

        return ApiResultGenerator.create("0", "数据获取成功!", info);
    }

    @Override
    public ApiResultDTO getToken(WxBO wxBO) {
        ApiResultDTO apiResultDTO;

        //查找manager信息
        BwechatUserPO bwechatUserPO = bwechatUserRepository.findByPhone(wxBO.getPhoneNumber());
        if(bwechatUserPO == null) {
            // 保存managerUser数据
            BwechatUserPO info = new BwechatUserPO();
            info.setPhone(wxBO.getPhoneNumber());
            info.setOpenId(wxBO.getOpenid());
            info.setUnionId(wxBO.getUnionId());
            bwechatUserRepository.save(info);
        }
        String token;
        try {
            // 获取token并存储到redis
            token = JwtUtil.generateToken(wxBO.getPhoneNumber(), wxBO.getOpenid(), wxBO.getUnionId(), wxBO.getLoginType());
            redisTemplate.opsForValue().set(JwtUtil.JWT_SHIRO_CACHE_KEY_PREFIX + wxBO.getPhoneNumber(), token, JwtUtil.MEMBER_EXPIRE_TIME, TimeUnit.SECONDS);
        }catch (Exception e){
            e.printStackTrace();
            apiResultDTO = ApiResultGenerator.create("-1", "获取token失败");
            return apiResultDTO;
        }

        return ApiResultGenerator.create("0", "数据获取成功!", token);
    }


    @Override
    public ApiResultDTO compareTempExpertInfo(WxBO wxBO) {
        ApiResultDTO apiResultDTO;
        //根据姓名查询临时专家
        List<TempExpertPo> tepExpertList = tempExpertRepository.findAllByRealNameAndOrgIDAndDeletedIsFalse(wxBO.getRealName(), wxBO.getOrgId());
        if(!CollectionUtils.isEmpty(tepExpertList)){
            if(tepExpertList.size() > 1){
                apiResultDTO = ApiResultGenerator.create("-1", "当前姓名："+wxBO.getRealName()+"在所填写智库存在同名，请联系机构确认！");
            }else{
                // 返回临时专家的成果
                TempExpertPo tempExpertPo = tepExpertList.get(0);

                // 判断关联关系
                OrgUserRelPo rel = orgInviteService.getRel(wxBO.getPhoneNumber(), wxBO.getOrgId());
                if (rel == null) {
                    //建立用户信息
                    OrgUserPo newUserPO = this.buildUserInfo(wxBO.getPhoneNumber(), wxBO.getRealName(), wxBO.getOrgId(), wxBO.getFullTime());
                    // 该用户的成果中的作者id 设置成新的id
                    fruitAuthorRepository.updateAuthorId(tempExpertPo.getId(), newUserPO.getId());
                    // 修改该用户的关联关系 设置成新的id
                    fruitOrgRelRepository.updateAuthorId(tempExpertPo.getId(), newUserPO.getId());
                    // 修改临时专家为false
                    tempExpertRepository.logicDelete(tempExpertPo.getId());

                } else if (rel.isMgr() && !rel.isExpert()) {
                    // 如果只有管理员角色关系,执行设置专家关系
                    rel.setExpert(true);
                    orgUserRelRepository.save(rel);
                }

                //获取token
                apiResultDTO = this.getToken(wxBO);
            }
        }else{
            //添加待审核记录
            wxCheckUserService.saveWxCheckUserData(wxBO.getRealName(), wxBO.getPhoneNumber(), wxBO.getOrgId(), "1");

            apiResultDTO = ApiResultGenerator.create("-2", "请等待智库审核！");
        }

        return apiResultDTO;
    }

    @Override
    public OrgUserPo buildUserInfo(String phoneNumber, String realName, Long orgId, boolean fullTIme){
        // 封装用户信息入库
        OrgExpertInfoPo orgExpertInfoPo = new OrgExpertInfoPo();
        orgExpertInfoRepository.save(orgExpertInfoPo);

        OrgUserPo orgUserPo = new OrgUserPo();
        orgUserPo.setPhoneNumber(phoneNumber);
        orgUserPo.setRealName(RegularExpressionUtil.filterSpace(realName));
        orgUserPo.setPassword("");
        orgUserPo.setExpertInfo(orgExpertInfoPo);
        OrgUserPo savedUserPo = orgUserRepository.save(orgUserPo);

        // 绑定该用户与机构关系
//        OrgPo orgPo = orgRepository.findById(orgId).orElse(null);
        OrgDeptPo orgDeptPo = orgDeptService.getOne(orgId);
        if (orgDeptPo != null) {
            OrgUserRelPo orgUserRelPo = new OrgUserRelPo();
            orgUserRelPo.setUser(savedUserPo);
            orgUserRelPo.setOrg(orgDeptPo);
            orgUserRelPo.setFullTime(fullTIme);
            orgUserRelPo.setMgr(false);
            orgUserRelPo.setExpert(true);
            orgUserRelRepository.save(orgUserRelPo);
        }
        return savedUserPo;
    }

}
